import { _decorator, Node, instantiate, Label, tween, Vec2, UIOpacity, UITransform, v3, v2, EventTouch, Vec3, Prefab, sys, Component, Tween, random, randomRange, } from 'cc';
import UI from 'db://assets/Script/Manager/UI';
import JiuJiuXiaoDongWu_YangInfo from './Data/JiuJiuXiaoDongWu_YangInfo';
import JiuJiuXiaoDongWu_pfutil from './Data/JiuJiuXiaoDongWu_pfutil';
import JiuJiuXiaoDongWu_EnumDir from './Data/JiuJiuXiaoDongWu_EnumDir';
import JiuJiuXiaoDongWu_WinPanel from './UI/JiuJiuXiaoDongWu_WinPanel';
import { JiuJiuXiaoDongWu_GameData } from './Data/JiuJiuXiaoDongWu_GameData';
import { JiuJiuXiaoDongWu_GameStorage } from './Data/JiuJiuXiaoDongWu_GameStorage';
import JiuJiuXiaoDongWu_GamePanel from './UI/JiuJiuXiaoDongWu_GamePanel';
import { bdlMgr } from 'db://assets/Script/Manager/BundleManager_S';

const { ccclass, property } = _decorator;

@ccclass
export default class JiuJiuXiaoDongWu_GameManager extends Component {
    public static Instance: JiuJiuXiaoDongWu_GameManager;

    @property(Node)
    container: Node = null;
    @property(Node)
    show: Node = null;
    // @property(Node)
    // zz: Node = null;  //遮罩
    @property(Node)
    btns: Node = null;  //按钮组
    @property(Node)
    chooose: Node = null;  //选择视图
    @property(Label)
    jsq: Label = null;  //计时器
    @property(Label)
    level: Label = null;  //关卡

    Prefab_Yang: Prefab | null = null;

    public grids_nums: Array<number> = []
    public grids: Map<number, number> = new Map();
    public yangs: Array<JiuJiuXiaoDongWu_YangInfo> = [];
    public h_c = 20;
    public l_c = 20;
    public ww = 50;
    public oper: Array<JiuJiuXiaoDongWu_YangInfo> = [];
    public game_flag = false;
    public pause_flag = false;

    arr_node: Node[] = [];

    async onLoad() {
        JiuJiuXiaoDongWu_GameManager.Instance = this;

        JiuJiuXiaoDongWu_GameStorage.initData();

        JiuJiuXiaoDongWu_GameManager.Instance.Prefab_Yang = await bdlMgr.getRes<Prefab>(`JiuJiuXiaoDongWu_Prefab`, `Yang`, Prefab);
        JiuJiuXiaoDongWu_GameManager.Instance.startGame();
    }

    start() {
        JiuJiuXiaoDongWu_GamePanel.Instance.ShowOn();
    }

    ShowOn() {
        this.node.active = true;
        this.AddListener();
    }

    AddListener() {
    }

    public cleanData() {
        this.grids_nums = [];
        this.grids = new Map();

        this.yangs = [];

        this.container.removeAllChildren();

        // this.zz.parent = this.container;
        this.chooose.active = false
    }

    public startGame() {
        this.pause_flag = false;

        this.cleanData();
        this.randYang();
        this.updateView();

        this.level.string = "第 " + JiuJiuXiaoDongWu_GameData.Get_level() + " 关";

        this.scheduleOnce(() => {
            this.checkShow();

            let arr = [];
            for (let index = 0; index < JiuJiuXiaoDongWu_GameManager.Instance.yangs.length; index++) {
                const item = JiuJiuXiaoDongWu_GameManager.Instance.yangs[index];
                arr.push(item.yang);
            }
            this.arr_node = arr;


            // this.scheduleOnce(() => {
            JiuJiuXiaoDongWu_GameData.fitToScreenWithRotation(JiuJiuXiaoDongWu_GameManager.Instance.container);
            // }, 0.01)

            // console.log(`动物数量*---------`, JiuJiuXiaoDongWu_GameManager.Instance.yangs.length)
        }, 0.1)
    }

    getV_power_scale(lv: number): number {
        return 1
        return 1.8 * Math.pow(lv, -0.398);
    }

    getRotationByLevel(level: number): number {
        const angles = [0, 45, 30, 90, 45, 60,];
        const index = (level - 1) % angles.length;
        return angles[index];
    }

    setLvData() {
        let lv = JiuJiuXiaoDongWu_GameData.Get_level();

        // let count = JiuJiuXiaoDongWu_GameData.getCountByLevelWithMax(lv + 1, 3, 1, 5, 30, 6);
        let count = JiuJiuXiaoDongWu_GameData.getQuantityByLevel(lv);
        // console.log(`count*---------`, count)

        this.l_c = count;
        this.h_c = count;

        // let scale = this.getV_power_scale(lv);
        // this.container.scale = v3(scale, scale, scale);

        let angle = this.getRotationByLevel(lv);
        // console.log(`angle----------`, angle);
        this.container.angle = angle;

        let s = 1
        this.container.scale = v3(s, s, s);
    }

    private dirs: Array<number> = [1, 2, 3, 4];

    public randYang() {
        this.setLvData();

        this.yangs = [];

        for (let i = 0; i < this.l_c; i++) {
            for (let k = 0; k < this.h_c; k++) {
                this.grids_nums.push(i * 10000 + k);
                this.grids.set(i * 10000 + k, 0);
            }
        }

        // console.log(`this.grids`, this.grids);
        // console.log(`this.grids_nums`, this.grids_nums);

        // JiuJiuXiaoDongWu_pfutil.randSort(this.grids_nums);

        let index = 0;

        while (true) {
            if (this.grids_nums.length == 0) {
                break;
            }

            // JiuJiuXiaoDongWu_pfutil.randSort(this.dirs);

            let flag = false;

            if (JiuJiuXiaoDongWu_pfutil.random(0, 100) < 50) {
                for (let i = 0; i < 4; i++) {
                    let id = this.grids_nums[0];

                    let id2 = this.getNextGrid(id, this.dirs[i]);

                    if (id2 == -1) {
                        continue;
                    }

                    if (this.grids.get(id2) == 1) {
                        continue;
                    }

                    let info = new JiuJiuXiaoDongWu_YangInfo();
                    info.dir = this.dirs[i];
                    info.grids.push(id);
                    info.grids.push(id2);

                    this.grids.set(id, 1);
                    this.grids.set(id2, 1);

                    JiuJiuXiaoDongWu_pfutil.removeVal(this.grids_nums, id);
                    JiuJiuXiaoDongWu_pfutil.removeVal(this.grids_nums, id2);

                    this.yangs.push(info);

                    flag = true;

                    break;
                }
            }

            if (flag == false) {
                // console.warn("咋回事呀");
                this.grids_nums.shift();
            }

            index++;

            if (index > 10000) {
                break;
            }
        }

        if (JiuJiuXiaoDongWu_GameData.Get_level() == 1 && this.canAllOut() == false) {
            this.randYang();
        }

        if (this.yangs.length < 4) {
            this.randYang();
        }
    }

    public getNextGrid(id: number, dir: number) {
        let i = Math.floor(id / 10000);
        let k = id % 10000;

        if (dir == JiuJiuXiaoDongWu_EnumDir.up) {
            k--;
        }
        else if (dir == JiuJiuXiaoDongWu_EnumDir.down) {
            k++;
        }
        else if (dir == JiuJiuXiaoDongWu_EnumDir.left) {
            i--;
        }
        else if (dir == JiuJiuXiaoDongWu_EnumDir.right) {
            i++;
        }

        let val = i * 10000 + k;

        if (this.grids.has(val) == true) {
            return val;
        }
        else {
            return -1;
        }
    }

    public updateView() {
        for (let i = 0; i < this.yangs.length; i++) {
            let yang = this.getYang(this.yangs[i]);
            yang.parent = this.container;


            yang.getComponent(UIOpacity).opacity = 255;

            this.yangs[i].yang = yang;
            yang.getComponent(UIOpacity).opacity = 0;
        }
    }

    public getYang(info: JiuJiuXiaoDongWu_YangInfo): Node {
        let node: Node;

        if (info.yang == null) {
            // node = instantiate(PrefabManager.getPrefab("Yang"));
            node = instantiate(JiuJiuXiaoDongWu_GameManager.Instance.Prefab_Yang);

            // console.warn("创建的羊---"+(<any>node)._id)
        }
        else {
            node = info.yang;
        }

        let x = Math.floor(info.grids[0] / 10000);
        let y = info.grids[0] % 10000;

        x = (x * this.ww - this.ww / 2 * this.l_c) + this.ww / 2;

        y = (this.ww / 2 * this.h_c - y * this.ww) - this.ww / 2;

        if (info.dir == JiuJiuXiaoDongWu_EnumDir.up) {
            y += this.ww / 2;
            node.angle = 0

        }
        else if (info.dir == JiuJiuXiaoDongWu_EnumDir.down) {
            y -= this.ww / 2;

            node.angle = 180
        }
        else if (info.dir == JiuJiuXiaoDongWu_EnumDir.left) {
            x -= this.ww / 2;

            node.angle = 90
        }
        else if (info.dir == JiuJiuXiaoDongWu_EnumDir.right) {
            x += this.ww / 2;

            node.angle = 270
        }

        // node.x = x;
        // node.y = y;
        node.position = v3(x, y);

        return node;
    }

    distance: number = 0;

    public delYang(info: JiuJiuXiaoDongWu_YangInfo) {
        for (let i = 0; i < this.yangs.length; i++) {
            if (this.yangs[i] == info) {
                console.warn("删除的羊---" + (<any>this.yangs[i].yang)._id)

                this.yangs.splice(i, 1);
            }
        }
    }

    //检测展示
    public checkShow() {
        let arr = [];

        let show_fw = this.node.getComponent(UITransform).convertToWorldSpaceAR(new Vec3(0, 0));

        let up = show_fw.y - this.show.getComponent(UITransform).height / 2;
        let down = show_fw.y + this.show.getComponent(UITransform).height / 2;
        let left = show_fw.x - this.show.getComponent(UITransform).width / 2;
        let right = show_fw.x + this.show.getComponent(UITransform).width / 2;

        for (let i = 0; i < this.yangs.length; i++) {
            let yang = this.yangs[i];

            let curr_pos = yang.yang.parent.getComponent(UITransform).convertToWorldSpaceAR(v3(yang.yang.position.x, yang.yang.position.y));

            if (curr_pos.x < left) {
                arr.push(yang);
                continue;
            }

            if (curr_pos.x > right) {
                arr.push(yang);
                continue;
            }

            if (curr_pos.y < up) {
                arr.push(yang);
                continue;
            }

            if (curr_pos.y > down) {
                arr.push(yang);
                continue;
            }
        }

        for (let i = 0; i < arr.length; i++) {
            for (let k = 0; k < this.yangs.length; k++) {
                if (this.yangs[k] == arr[i]) {
                    this.yangs[k].yang.parent = null;

                    for (let a = 0; a < this.yangs[k].grids.length; a++) {
                        this.grids.set(this.yangs[k].grids[a], 0);
                    }

                    //   console.warn("不展示的羊---"+(<any>this.yangs[k].yang)._id)
                    this.yangs.splice(k, 1);

                    break;
                }
            }
        }

        this.checkDir();

        for (let i = 0; i < this.yangs.length; i++) {
            let yang = this.yangs[i];
            yang.yang.scale = v3(0, 0, 0);
            yang.yang.getComponent(UIOpacity).opacity = 255;

            // tween(yang.yang)
            //     // .delay(JiuJiuXiaoDongWu_pfutil.random(100, this.distance00) / 1000)
            //     // .delay(randomRange(0, 0.6))
            //     .to(0.1, { scale: v3(1, 1, 1) })
            //     .start();

            yang.yang.scale = v3(1, 1, 1);

        }

        this.game_flag = true;
    }

    //检测可以跑出去的羊
    public checkOut(): Array<JiuJiuXiaoDongWu_YangInfo> {
        let arr: Array<JiuJiuXiaoDongWu_YangInfo> = [];

        for (let a = 0; a < this.yangs.length; a++) {
            let info = this.yangs[a];

            let i = Math.floor(info.grids[0] / 10000);
            let k = info.grids[0] % 10000;

            if (this.grids.get(info.grids[0]) == 0) {
                continue;
            }

            let add = 0;

            if (info.dir == JiuJiuXiaoDongWu_EnumDir.up) {
                k -= 1;

                while (true) {
                    add += 1;

                    if (k - add < 0) {
                        add = 100;
                        break;
                    }

                    if (this.grids.get(i * 10000 + (k - add)) == 1) {
                        add -= 1;
                        break;
                    }
                }

                if (add == 100) {
                    arr.push(info);
                }
            }
            else if (info.dir == JiuJiuXiaoDongWu_EnumDir.down) {
                k += 1;

                while (true) {
                    add += 1;

                    if (k + add >= this.h_c) {
                        add = 100;
                        break;
                    }

                    if (this.grids.get(i * 10000 + (k + add)) == 1) {
                        add -= 1;
                        break;
                    }
                }

                if (add == 100) {
                    arr.push(info);
                }
            }
            else if (info.dir == JiuJiuXiaoDongWu_EnumDir.left) {
                i -= 1;

                while (true) {
                    add += 1;

                    if (i - add < 0) {
                        add = 100;
                        break;
                    }

                    if (this.grids.get((i - add) * 10000 + k) == 1) {
                        add -= 1;
                        break;
                    }
                }

                if (add == 100) {
                    arr.push(info);
                }
            }
            else if (info.dir == JiuJiuXiaoDongWu_EnumDir.right) {
                i += 1;

                while (true) {
                    add += 1;

                    if (i + add >= this.l_c) {
                        add = 100;
                        break;
                    }

                    if (this.grids.get((i + add) * 10000 + k) == 1) {
                        add -= 1;
                        break;
                    }
                }

                if (add == 100) {
                    arr.push(info);
                }
            }
        }

        return arr;
    }

    public canAllOut() {
        let jilu: Array<number> = [];

        while (true) {
            let aa = this.checkOut();

            if (aa.length == 0) {
                console.error("不可全部消除");
                break;
            }

            for (let i = 0; i < aa.length; i++) {
                for (let k = 0; k < aa[i].grids.length; k++) {
                    jilu.push(aa[i].grids[k]);
                    this.grids.set(aa[i].grids[k], 0);
                }
            }

            if (jilu.length == this.yangs.length * 2) {
                // console.error("可以全部消除")

                for (let i = 0; i < jilu.length; i++) {
                    this.grids.set(jilu[i], 1);
                }

                return true;
            }
        }

        return false;
    }

    //撤回
    public 撤回() {
        if (this.oper.length == 0) {
            // MdTip.inst.showTip("没有可撤回的操作");
            return;
        }

        let info = this.oper.pop();

        if (info.move != null) {
            info.move.stop();
        }

        for (let i = 0; i < info.grids.length; i++) {
            this.grids.set(info.grids[i], 0);
        }

        info.huiChe();

        for (let i = 0; i < info.grids.length; i++) {
            this.grids.set(info.grids[i], 1);
        }

        info.yang = this.getYang(info);

        if (this.yangs.indexOf(info) == -1) {
            this.yangs.push(info);
        }
    }

    // //高亮
    // public gaoLiang() {
    //     let arr = this.checkOut();

    //     if (arr.length == 0) {
    //         // MdTip.inst.showTip("没有可消除的动物");
    //         return;
    //     }

    //     this.zz.active = true;

    //     // @ts-ignore
    //     this.zz.zIndex = 99;

    //     for (let i = 0; i < arr.length; i++) {
    //         // @ts-ignore
    //         arr[i].yang.zIndex = 100;
    //     }
    // }

    public fz_flag = false;
    public fanZhuan1() {
        if (this.yangs.length == 0) {
            return;
        }

        this.btns.active = false;

        this.fz_flag = true;

        this.chooose.active = true;

        for (let i = 0; i < this.yangs.length; i++) {
            // @ts-ignore
            this.yangs[i].yang.zIndex = 100;
        }

        // console.log('JiuJiuXiaoDongWu_GameManager.Instance.fz_flag:', JiuJiuXiaoDongWu_GameManager.Instance.fz_flag);
    }

    public fanZhuan2(info: JiuJiuXiaoDongWu_YangInfo) {
        if (this.yangs.length == 0) {
            return;
        }

        this.btns.active = true;

        this.fz_flag = false;

        this.chooose.active = false;

        this.fanZhuan3(info);
    }

    public fanZhuan3(info: JiuJiuXiaoDongWu_YangInfo) {
        info.dir = (info.dir - 1 + 2) % 4 + 1;
        info.grids.reverse();

        info.yang = this.getYang(info);
    }

    private checkDir() {
        let map: Map<number, Array<JiuJiuXiaoDongWu_YangInfo>> = new Map();

        let map2: Map<number, Array<JiuJiuXiaoDongWu_YangInfo>> = new Map();

        for (let i = 0; i < this.yangs.length; i++) {
            let info = this.yangs[i];

            if (info.dir == JiuJiuXiaoDongWu_EnumDir.left || info.dir == JiuJiuXiaoDongWu_EnumDir.right) {
                let g = Math.floor(info.grids[0] % 10000);

                if (info.dir == JiuJiuXiaoDongWu_EnumDir.right) {
                    this.fanZhuan3(info);
                }

                if (map.has(g) == false) {
                    map.set(g, new Array());
                }

                map.get(g).push(info);
            }
            else {

                if (info.dir == JiuJiuXiaoDongWu_EnumDir.down) {
                    this.fanZhuan3(info);
                }

                let g = Math.floor(info.grids[0] / 10000);

                if (map2.has(g) == false) {
                    map2.set(g, new Array());
                }

                map2.get(g).push(info);
            }
        }

        map.forEach((val: Array<JiuJiuXiaoDongWu_YangInfo>, key) => {
            val.sort((v1, v2) => {
                let a1 = Math.floor(v1.grids[0] / 10000);
                let a2 = Math.floor(v2.grids[0] / 10000);
                return a1 - a2;
            })

            let index = JiuJiuXiaoDongWu_pfutil.random(0, val.length + 1);

            for (let i = index; i < val.length; i++) {
                this.fanZhuan3(val[i]);
            }
        });

        map2.forEach((val: Array<JiuJiuXiaoDongWu_YangInfo>, key) => {
            val.sort((v1, v2) => {
                let a1 = Math.floor(v1.grids[0] % 10000);
                let a2 = Math.floor(v2.grids[0] % 10000);
                return a1 - a2;
            })

            let index = JiuJiuXiaoDongWu_pfutil.random(0, val.length + 1);

            for (let i = index; i < val.length; i++) {
                this.fanZhuan3(val[i]);
            }
        });
    }

    public update() {
        // if (this.game_flag == true) {
        //     if (this.yangs.length == 0) {
        //         this.game_flag = false;

        //         this.gameOver();
        //     }
        // }
    }

    gameOver() {
        setTimeout(() => {
            UI.Instance.CreatePanel_sub(`JiuJiuXiaoDongWu_Prefab`, `UI/JiuJiuXiaoDongWu_WinPanel`, JiuJiuXiaoDongWu_WinPanel);
        }, 300);
    }

    上一关() {
        JiuJiuXiaoDongWu_GameData.Set_level(JiuJiuXiaoDongWu_GameData.Get_level() - 1);
        JiuJiuXiaoDongWu_GameManager.Instance.startGame();
    }

    下一关() {
        let level = JiuJiuXiaoDongWu_GameData.Get_level();
        let next_level = level + 1;

        // console.log(`level`, level);
        // console.log(`next_level`, next_level);

        JiuJiuXiaoDongWu_GameData.Set_level(next_level);
        JiuJiuXiaoDongWu_GameManager.Instance.startGame();
    }
}

window['JiuJiuXiaoDongWu_GameManager'] = JiuJiuXiaoDongWu_GameManager;